{{>partial_header}}
package {{packageName}}

import (
	"encoding/json"
	"net/http"
	"strings"

{{#routers}}
	{{#mux}}
	"github.com/gorilla/mux"
	{{/mux}}
	{{#chi}}
	"github.com/go-chi/chi/v5"
	{{/chi}}
{{/routers}}
)

// {{classname}}Controller binds http requests to an api service and writes the service results to the http response
type {{classname}}Controller struct {
	service {{classname}}Servicer
	errorHandler ErrorHandler
}

// {{classname}}Option for how the controller is set up.
type {{classname}}Option func(*{{classname}}Controller)

// With{{classname}}ErrorHandler inject ErrorHandler into controller
func With{{classname}}ErrorHandler(h ErrorHandler) {{classname}}Option {
	return func(c *{{classname}}Controller) {
		c.errorHandler = h
	}
}

// New{{classname}}Controller creates a default api controller
func New{{classname}}Controller(s {{classname}}Servicer, opts ...{{classname}}Option) Router {
	controller := &{{classname}}Controller{
		service:      s,
		errorHandler: DefaultErrorHandler,
	}

	for _, opt := range opts {
		opt(controller)
	}

	return controller
}

// Routes returns all of the api route for the {{classname}}Controller
func (c *{{classname}}Controller) Routes() Routes {
	return Routes{ {{#operations}}{{#operation}}
		{
			"{{operationId}}",
			strings.ToUpper("{{httpMethod}}"),
			"{{{basePathWithoutHost}}}{{{path}}}",
			c.{{operationId}},
		},{{/operation}}{{/operations}}
	}
}{{#operations}}{{#operation}}

// {{nickname}} - {{{summary}}}
{{#isDeprecated}}
// Deprecated
{{/isDeprecated}}
func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Request) {
	{{#hasFormParams}}
	{{#isMultipart}}
	if err := r.ParseMultipartForm(32 << 20); err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isMultipart}}
	{{^isMultipart}}
	if err := r.ParseForm(); err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isMultipart}}
	{{/hasFormParams}}
	{{#routers}}
		{{#mux}}
			{{#hasPathParams}}
	params := mux.Vars(r)
			{{/hasPathParams}}
		{{/mux}}
	{{/routers}}
	{{#hasQueryParams}}
	query := r.URL.Query()
	{{/hasQueryParams}}
	{{#allParams}}
	{{#isPathParam}}
	{{#isLong}}
	{{paramName}}Param, err := parseInt64Parameter({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}, {{required}})
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isLong}}
	{{#isInteger}}
	{{paramName}}Param, err := parseInt32Parameter({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}, {{required}})
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isInteger}}
	{{^isLong}}
	{{^isInteger}}
	{{paramName}}Param := {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}
	{{/isInteger}}{{/isLong}}
	{{/isPathParam}}
	{{#isQueryParam}}
	{{#isLong}}
	{{paramName}}Param, err := parseInt64Parameter(query.Get("{{baseName}}"), {{required}})
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isLong}}
	{{#isInteger}}
	{{paramName}}Param, err := parseInt32Parameter(query.Get("{{baseName}}"), {{required}})
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isInteger}}
	{{#isBoolean}}
	{{paramName}}Param, err := parseBoolParameter(query.Get("{{baseName}}"))
	if err != nil {
		w.WriteHeader(500)
		return
	}
	{{/isBoolean}}
	{{^isLong}}
	{{^isInteger}}
	{{^isBoolean}}
	{{paramName}}Param := {{#isArray}}strings.Split({{/isArray}}query.Get("{{baseName}}"){{#isArray}}, ","){{/isArray}}
	{{/isBoolean}}
	{{/isInteger}}
	{{/isLong}}
	{{/isQueryParam}}
	{{#isFormParam}}
	{{#isFile}}{{#isArray}}
	{{paramName}}Param, err := ReadFormFilesToTempFiles(r, "{{baseName}}"){{/isArray}}{{^isArray}}
	{{paramName}}Param, err := ReadFormFileToTempFile(r, "{{baseName}}")
	{{/isArray}}
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isFile}}
	{{#isLong}}{{#isArray}}
	{{paramName}}Param, err := parseInt64ArrayParameter(r.FormValue("{{baseName}}"), ",", {{required}}){{/isArray}}{{^isArray}}
	{{paramName}}Param, err := parseInt64Parameter(r.FormValue("{{baseName}}"), {{required}}){{/isArray}}
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isLong}}
	{{#isInteger}}{{#isArray}}
	{{paramName}}Param, err := parseInt32ArrayParameter(r.FormValue("{{baseName}}"), ",", {{required}}){{/isArray}}{{^isArray}}
	{{paramName}}Param, err := parseInt32Parameter(r.FormValue("{{baseName}}"), {{required}}){{/isArray}}
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{/isInteger}}
	{{^isFile}}
	{{^isLong}}
	{{paramName}}Param := r.FormValue("{{baseName}}")
	{{/isLong}}
	{{/isFile}}
	{{/isFormParam}}
	{{#isHeaderParam}}
	{{paramName}}Param := r.Header.Get("{{baseName}}")
	{{/isHeaderParam}}
	{{#isBodyParam}}
	{{paramName}}Param := {{dataType}}{}
	d := json.NewDecoder(r.Body)
	{{^isAdditionalPropertiesTrue}}
	d.DisallowUnknownFields()
	{{/isAdditionalPropertiesTrue}}
	if err := d.Decode(&{{paramName}}Param); err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	{{#isArray}}
		{{#items.isModel}}
	for _, el := range {{paramName}}Param {
		if err := Assert{{baseType}}Required(el); err != nil {
			c.errorHandler(w, r, err, nil)
			return
		}
	}
		{{/items.isModel}}
	{{/isArray}}
	{{^isArray}}
		{{#isModel}}
	if err := Assert{{baseType}}Required({{paramName}}Param); err != nil {
		c.errorHandler(w, r, err, nil)
		return
	}
		{{/isModel}}
	{{/isArray}}
	{{/isBodyParam}}
	{{/allParams}}
	result, err := c.service.{{nickname}}(r.Context(){{#allParams}}, {{paramName}}Param{{/allParams}})
	// If an error occurred, encode the error with the status code
	if err != nil {
		c.errorHandler(w, r, err, &result)
		return
	}
	// If no error, encode the body and the result code
	EncodeJSONResponse(result.Body, &result.Code,{{#addResponseHeaders}} result.Headers,{{/addResponseHeaders}} w)

}{{/operation}}{{/operations}}
